type name = string;;
type age = int;;
type adress = string;;
type telephone = int;;
type contact = (name * age * adress * telephone);;
type agenda = contact list;;

let l1 = [1;3;5;7;11];;

(*3.1 Les listes*)

let rec exist x l = match l with
    [] -> false
  |e::l -> x=e||exist x l;;

let rec add_list x l = match l with
    [] -> x::[]
  |e::l when e<x -> e::(add_list x l)
  |e::l when x=e -> e::l
  |e::l -> x::e::l;;

let rec remove_list x l =  match l with
    [] -> []
  |e::l when e<x -> e::(remove_list x l)
  |e::l when x=e -> l
  |e::l -> e::l;;

(*3.2 Introduction des fonctions sur l’ordre supérieur*)

let rec map f l = match l with
    [] -> []
  |e::l -> f e::map f l;;

let rec iter f l = match l with
    [] -> ()
  | e::l -> (f e);(iter f l);;

let rec for_all f l = match l with
    [] -> true
  |e::l -> f e&&for_all f l;;

(*3.3 Manipulation des caractères*)

let upper_case char = if int_of_char char>=97&&int_of_char char<=122 then char_of_int (int_of_char char - 32) else char;;

let lower_case char =  if int_of_char char>=65&&int_of_char char<=90 then char_of_int (int_of_char char + 32) else char;;

(*3.4 Manipulation des chaînes*)

let string_of_char c = String.make 1 c;;

let string_apply f str = 
  let length = (String.length str) - 1 in 
    let rec parse str i newstr = match i with
      i when i<=length -> (string_of_char (f str.[i])^newstr)^ parse str (i+1) newstr
    | length -> newstr
    in parse str 0 "";;

let string_uppercase chaine = string_apply (upper_case) chaine;;

let string_lowercase chaine = string_apply (lower_case) chaine;;
